package com.homedo.async.mysql.support.prepare.update;

import com.blinkfox.zealot.bean.SqlInfo;
import com.blinkfox.zealot.core.ZealotKhala;
import com.homedo.async.mysql.support.meta.EntityMetaData;
import com.homedo.async.mysql.support.prepare.util.CollectRecordColumnValUtil;
import com.homedo.plainly.logger.Logger;
import com.homedo.plainly.logger.LoggerFactory;

import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.Map;

/**
 * @author jgshun
 * @date 2020/3/5 1:56 PM
 */
public abstract class Record2Sql4Update {
    private static final Logger _LOGGER = LoggerFactory.getLogger(Record2Sql4Update.class);

    public static <T> Object[] prepare(T record, EntityMetaData<T> entityMetaData, boolean includeNullVals) {
        Field primaryKeyField = entityMetaData.getPrimaryKeyField();
        if (primaryKeyField == null) {
            throw new RuntimeException("[主键不存在:" + entityMetaData.getEntityClazs() + "]");
        }

        String idColumnName = entityMetaData.getFieldColumNameMapping().get(primaryKeyField).toString();

        Object[] prepareSelectSql = new Object[2];

        ZealotKhala sqlKhala = ZealotKhala.start()
                .update(entityMetaData.getTableName());

        Map<String, Object> columnNameValMap = CollectRecordColumnValUtil.collect(record, entityMetaData, includeNullVals);

        if (!columnNameValMap.isEmpty()) {

            sqlKhala.set(" ");

            Iterator<Map.Entry<String, Object>> colValIterator = columnNameValMap.entrySet().iterator();

            boolean isFirst = true;

            while (colValIterator.hasNext()) {
                Map.Entry<String, Object> curColVal = colValIterator.next();

                if (curColVal.getKey().equals(idColumnName)) {
                    continue;
                }

                if (isFirst) {
                    isFirst = false;
                } else {
                    sqlKhala.text(", ");
                }

                sqlKhala.equal(curColVal.getKey(), curColVal.getValue());
            }

            sqlKhala.where(" ");

            primaryKeyField.setAccessible(true);

            try {
                sqlKhala.equal(idColumnName, primaryKeyField.get(record));
            } catch (IllegalAccessException ex) {
                _LOGGER.error("[获取主键值失败：{},{}]", sqlKhala.end().getSql(), record, ex);
                throw new RuntimeException("[获取主键值失败]");
            }

        } else {
            _LOGGER.error("[缺少更新条件，禁止全表更新：{}]", sqlKhala.end().getSql(), record);
            throw new RuntimeException("[缺少更新条件，禁止全表更新]");
        }

        SqlInfo sqlInfo = sqlKhala.end();

        prepareSelectSql[0] = sqlInfo.getSql();
        prepareSelectSql[1] = sqlInfo.getParams();

        return prepareSelectSql;
    }

}

